package jinyilw.swing.icon;

import jinyilw.common.TextTools;
import jinyilw.swing.ComponentTools;
import jinyilw.swing.ResourceManager;
import jinyilw.swing.ScreenTools;
import jinyilw.swing.graphics.GraphicsTools;
import jinyilw.swing.image.ImageTools;

import javax.swing.Icon;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;

public class LazyScaleIcon implements Icon
{
	protected static boolean retina = ScreenTools.isRetina();
	protected static double systemScaleFactor = GraphicsTools
			.getSystemScaleFactor();
	private Class<?> loadClass = LazyScaleIcon.class;
	private String path;
	private URL url;
	private File file;
	protected volatile BufferedImage image;
	protected int w = 14, h = 14;
	protected Dimension size;
	private float contrast = 1.2f, lightness = 1.2f;

	private BufferedImage overImage;

	public static LazyScaleIcon getIcon(Class<?> loadClass, String path)
	{
		if (TextTools.isBlank(path))
			return null;
		return new LazyScaleIcon(loadClass, path);
	}

	public static LazyScaleIcon getIcon(URL url)
	{
		if (url == null)
			return null;
		return new LazyScaleIcon(url);
	}

	public static LazyScaleIcon getIcon(File file)
	{
		if (file == null)
			return null;
		return new LazyScaleIcon(file);
	}

	public LazyScaleIcon(Class<?> loadClass, String path)
	{
		if (loadClass != null)
			this.loadClass = loadClass;
		this.path = path;
	}

	public LazyScaleIcon(Class<?> loadClass, String path, float contrast,
			float lightness)
	{
		if (loadClass != null)
			this.loadClass = loadClass;
		this.path = path;
		this.contrast = contrast;
		this.lightness = lightness;
	}

	public LazyScaleIcon(URL url)
	{
		this.url = url;
	}

	public LazyScaleIcon(File file)
	{
		this.file = file;
	}

	public synchronized Image getImage()
	{
		if (image == null)
		{
			image = getOriginalImage();
			if (image == null)
				return null;
			w = image.getWidth() / 2;
			h = image.getHeight() / 2;
			if (!retina)
			{
				int ww = (int) (w * systemScaleFactor);
				int hh = (int) (h * systemScaleFactor);
				image = ImageTools.getShapedImage(image, ww, hh);
			}
		}
		return image;
	}

	protected BufferedImage getOriginalImage()
	{
		if (url != null)
			return ResourceManager.getBufferedImage(url);
		if (path != null)
		{
			url = loadClass.getResource(path);
			return ResourceManager.getBufferedImage(url);
		}
		if (file != null)
			return ResourceManager.getBufferedImage(file);
		return null;
	}

	public BufferedImage getOverImage()
	{
		if (overImage == null)
			overImage = ImageTools.getContrastLightImage(getImage(), contrast,
					lightness);
		return overImage;
	}
	@Override
	public int getIconWidth()
	{
		getImage();
		return w;
	}

	@Override
	public int getIconHeight()
	{
		getImage();
		return h;
	}

	public Dimension getSize()
	{
		if (size == null)
		{
			getImage();
			size = new Dimension(w, h);
		}
		return size;
	}

	@Override
	public void paintIcon(Component c, Graphics g, int x, int y)
	{
		if (g == null)
			return;
		boolean isEnable = c == null || c.isEnabled();
		Composite composite = ComponentTools.applyEnableAlpha((Graphics2D) g,
				isEnable, 1f, 0.3f);
		if (getImage() != null)
		{
			g.drawImage(image, x, y, w, h, null);
		} else
		{
			g.setColor(Color.red);
			g.fillRect(x, y, 14, 14);
			g.setColor(Color.white);
			g.drawLine(x, y, x + 13, y + 13);
			g.drawLine(x + 13, y, x, y + 13);
		}
		if (!isEnable)
			((Graphics2D) g).setComposite(composite);
	}
}
